#!/usr/bin/env python

""" 
    Block. Which will contain a seqential list of RTLCode.
"""

__author__ = 'liwei79@gmail.com'

from RTLCode import *


class Jump:
    """ Jump or not Jump """

    def __repr__(self):
        return ""


class JumpNeeded(Jump):
    """ This is a JUMP and requires a target """

    def __init__(self, target ):
        self.target = target


class JumpUncond(JumpNeeded): 
    """ Uncondition jump """

    def __init__(self, target):
        JumpNeeded.__init__(self, target)

    def __repr__(self):
        return "\tgoto BB_%d" % self.target


class JumpCond(JumpNeeded): 
    """ Condition jump """

    def __init__(self, target, testReg):
        JumpNeeded.__init__(self, target)
        self.testReg = testReg

    def __repr__(self):
        return "\tif ( %s ) goto BB_%d" % (repr(self.testReg), self.target)


""" Export BB_START_ID to user of Block """
BB_START_ID = 1


class RTLBlock:
    """ 
        RTL Basic Block
        Represents the jump of the block and RTL codes inside the block.
    """

    def __init__(self, id):
        self.id = id
        self.codes = []
        self.jump = Jump()

    def appendCode(self, code):
        self.codes.append(code)

    def countCode(self):
        return len(self.codes)

    def setJump(self, jump):
        self.jump = jump

    def getJump(self):
        return self.jump

    def __repr__(self):
        str = "BB_%d:\n" % self.id
        for code in self.codes:
            str = str + repr(code) + "\n"
        if isinstance(self.jump, JumpNeeded):
            str = str + repr(self.jump) + "\n"
        return str


if __name__ == "__main__":
    bb = RTLBlock(1)
    bb2 = RTLBlock(2)
    bb.appendCode(CodeRout("foo", OpndLst([OpndReg("a"), OpndReg("b"), OpndReg("c")])))
    bb.appendCode(CodeBop(OpBinary("ADD"), OpndReg("a"), OpndReg("b"), OpndNum(10)))
    bb2.appendCode(CodeCall("bar", OpndLst([OpndReg("a"), OpndReg("b"), OpndReg("c")])))
    bb2.appendCode(CodeFunc(OpndReg("r"), "bar", OpndLst([OpndReg("a"), OpndReg("b"), OpndReg("c")])))
    bb.appendCode(CodeRet(OpndReg("a")))
    bb.setJump(JumpCond(2, OpndReg("z")))
    bb2.setJump(JumpUncond(1))
    print bb
    print bb2
            

